package com.wandousoushu.jiusen.booksource.data.entities

import android.os.Parcelable
import com.wandousoushu.jiusen.MyApplication
import com.wandousoushu.jiusen.booksource.bean.BaseBook
import com.wandousoushu.jiusen.booksource.constant.AppPattern
import com.wandousoushu.jiusen.booksource.constant.BookType
import com.wandousoushu.jiusen.booksource.model.BookManager
import com.wandousoushu.jiusen.util.GSON
import com.wandousoushu.jiusen.util.fromJsonObject
import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize
import java.nio.charset.Charset
import kotlin.math.max

@Parcelize
class Book(
        override var bookUrl: String = "",          // 详情页Url(本地书源存储完整文件路径)
        var tocUrl: String = "",                    // 目录页Url (toc=table of Contents)
        var origin: String = "0",        // 书源URL(默认BookType.local)
        var originName: String = "",                //书源名称 or 本地书籍文件名
        var name: String = "",                      // 书籍名称(书源获取)
        var author: String = "",                    // 作者名称(书源获取)
        override var kind: String? = null,          // 分类信息(书源获取)
        var customTag: String? = null,              // 分类信息(用户修改)
        var coverUrl: String? = null,               // 封面Url(书源获取)
        var customCoverUrl: String? = null,         // 封面Url(用户修改)
        var intro: String? = null,                  // 简介内容(书源获取)
        var customIntro: String? = null,            // 简介内容(用户修改)
        var charset: String? = null,                // 自定义字符集名称(仅适用于本地书籍)
        var type: Int = 0,                          // 0:text 1:audio
        var group: Int = 0,                         // 自定义分组索引号    1收藏 2书架
        var latestChapterTitle: String? = null,     // 最新章节标题
        var latestChapterTime: Long = System.currentTimeMillis(),            // 最新章节标题更新时间
        var lastCheckTime: Long = System.currentTimeMillis(),                // 最近一次更新书籍信息的时间
        var lastCheckCount: Int = 0,                // 最近一次发现新章节的数量
        var totalChapterNum: Int = 0,               // 书籍目录总数
        var durChapterTitle: String? = null,        // 当前章节名称
        var durChapterIndex: Int = 0,               // 当前章节索引
        var durChapterPos: Int = 0,                 // 当前阅读的进度(首行字符的索引位置)
        var durChapterTime: Long = System.currentTimeMillis(),               // 最近一次阅读书籍的时间(打开正文的时间)
        override var wordCount: String? = null,
        var canUpdate: Boolean = true,              // 刷新书架时更新书籍信息
        var order: Int = 0,                         // 手动排序
        var originOrder: Int = 0,                   //书源排序
        var useReplaceRule: Boolean = true,         // 正文使用净化替换规则
        var variable: String? = null                // 自定义书籍变量信息(用于书源规则检索书籍信息)
) : Parcelable, BaseBook {

    fun isLocalBook(): Boolean {
        return origin == BookType.local
    }

    fun isLocalTxt(): Boolean {
        return isLocalBook() && originName.endsWith(".txt", true)
    }

    fun isEpub(): Boolean {
        return originName.endsWith(".epub", true)
    }

    fun isOnLineTxt(): Boolean {
        return !isLocalBook() && type == 0
    }

    override fun equals(other: Any?): Boolean {
        if (other is Book) {
            return (other.bookUrl == bookUrl&&other.group==other.group)
        }
        return false
    }

    override fun hashCode(): Int {
        return bookUrl.hashCode()
    }

    @delegate:Transient
    @IgnoredOnParcel
    override val variableMap by lazy {
        GSON.fromJsonObject<HashMap<String, String>>(variable) ?: HashMap()
    }

    override fun putVariable(key: String, value: String) {
        variableMap[key] = value
        variable = GSON.toJson(variableMap)
    }

    @IgnoredOnParcel
    override var infoHtml: String? = null

    @IgnoredOnParcel
    override var tocHtml: String? = null

    fun getRealAuthor() = author.replace(AppPattern.authorRegex, "")

    fun getUnreadChapterNum() = max(totalChapterNum - durChapterIndex - 1, 0)

    fun getDisplayCover() = if (customCoverUrl.isNullOrEmpty()) coverUrl else customCoverUrl

    fun getDisplayIntro() = if (customIntro.isNullOrEmpty()) intro else customIntro

    fun fileCharset(): Charset {
        return charset(charset ?: "UTF-8")
    }

    fun toSearchBook(): SearchBook {
        return SearchBook(
            name = name,
            author = author,
            kind = kind,
            bookUrl = bookUrl,
            origin = origin,
            originName = originName,
            type = type,
            wordCount = wordCount,
            latestChapterTitle = latestChapterTitle,
            coverUrl = coverUrl,
            intro = intro,
            tocUrl = tocUrl,
            originOrder = originOrder,
            variable = variable
        ).apply {
            this.infoHtml = this@Book.infoHtml
            this.tocHtml = this@Book.tocHtml
        }
    }

    fun changeTo(newBook: Book) {
        //newBook.group = group
        newBook.order = order
        newBook.customCoverUrl = customCoverUrl
        newBook.customIntro = customIntro
        newBook.customTag = customTag
        newBook.canUpdate = canUpdate
        newBook.useReplaceRule = useReplaceRule
        //deleteShelf()
        //MyApplication.instance.UpdateChangeBook(newBook);
        //MyApplication.instance.AddBook(newBook);
        //App.db.bookDao().insert(newBook)
    }

    fun deleteShelf() {
        if (ReadBook.book?.bookUrl == bookUrl) {
            ReadBook.book = null
        }
        BookManager.GetInstance().RemoveBook(this,2);
        //App.db.bookDao().delete(this)
    }

    fun deleteMark() {
        if (ReadBook.book?.bookUrl == bookUrl) {
            ReadBook.book = null
        }
        BookManager.GetInstance().RemoveBookMark(this,1);
        //App.db.bookDao().delete(this)
    }
}